#ifndef _modelo_H_
#define _modelo_H_



#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

#include <iostream>
#include "SMATModel.hh"
#include "display.hh"
#include "utils.hh"
#include <string.h>

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>

#include <sys/time.h>
#include <unistd.h>
#include <sys/select.h>
#include "smat-ransac.h"


#include "videoAVI.h"
#include "constants.h"
#include "face_detect_vj.hh"
#include "modelo_RANSAC.h"
#include "read_video.h"
#include "other_functions.h"
#include "options.h"
#include <colores.h>

#include <iostream> 
using namespace std;

class CModel2D;

class CModel3D 
{
    friend class CModel2D;

 private:
    CvMat * points3D; //puntos 3d del modelo
    CvMat * angY; // ángulos de ocultamiento de cada punto
    int npoints;
    
    CvRect haar_modelo; // posicion predeterminada de box para la cara
    //solo para dibujar
    CvMat * lines;    //matriz que indica que puntos se unen a otros con lineas
    
    //datos intermedios
    CvMat * mask;

 public:
    //constructor
    CModel3D()
    {
	points3D =0;
	angY =0;
	npoints =0;
	lines =0;
	mask =0;
    };
    ~CModel3D()
    {
	if (points3D) cvReleaseMat(&points3D);
	if (angY) cvReleaseMat(&angY);
	if (lines) cvReleaseMat(&lines);
	if (mask) cvReleaseMat(&mask);
    
    };

    int do_Estereo(CModel2D *, IplImage ** , int n, 
		   struct corners_params_t*, bool graficar = false);
    void setpoints(int row, CvMat *);
    int clear_mat(CvMat * mask);
};

/*********************************************************************/

class CModel2D 
{
    friend class CModel3D;

 private:
    CvMat * points2D; // proyeccion de los puntos 3D sobre el plano
    CvMat * mask_hide; //puntos que están ocultos desde la posición de la vista
    CvMat * inivect;
    CvMat * epilines;

    //modelo de apariencia de la cara
    boost::shared_ptr<SMATModel> smat;
    std::vector<boost::shared_ptr<CvMat> > smat_pts;

    //indicadores de la pose
    CvMat *vect, *translation;
    CvMat *vect_media, *translation_media;
    CvMat *vect2, *translation2;
    CvMat * rotation_tmp;

    //datos de la calibración intrínseca
    CALIBRATION_PARAMS_t *cal;
    //datos de la calibración extrínseca entre dos vistas o cámaras
    STEREO_PARAMS_t *cal_ext;


    //datos de interés
    IplImage * frame; //vista con la que trabajar en cada frame

    CvRect haar_rect, haar_rect2;
    HaarDetector *ahaars;
    int nhaars;
    

    CModel3D *pmodel3D;



 public:
    //constructor
    CModel2D(CModel3D *, HaarDetector *haars, int n);
    //CModel2D(void);
    ~CModel2D();

    //aplicar el haar-like
    int detect (int n, IplImage * img);
    CvRect set_reduced_haar (void);
    void set_haar(CvRect);
    CvRect get_haar(void);

    CvMat * set_data(CvPoint2D32f * points, int n);
    void ComputeCorrespondEpilines(void);
    int FindStereoPoints(IplImage ** grey, CModel2D *model2D2, bool graficar);
    void setpoints(int row, CvMat *);
    void setpoints(int row, float, float);
    CvMat * copy_data(CvPoint2D32f * points2D32f, int npoints);
    int clear_mat(CvMat * mask);

    //go_ransac();

};


#endif //_modelo_RANSAC_H_
